﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.NumericalIntegration
{
    /// <summary>
    /// This class represents an abstract layer for all bivariate integrators.
    /// </summary>
    [Serializable]
    public abstract class AbstractBivariateIntegrator : AbstractMultivariateIntegrator
    {
        /// <summary>
        /// This field holds the first dimension lower bound of the integral.
        /// </summary>
        protected double a1;

        /// <summary>
        /// This field holds the second dimension lower bound of the integral.
        /// </summary>
        protected double a2;

        /// <summary>
        /// This field holds the first dimension upper bound of the integral.
        /// </summary>
        protected double b1;

        /// <summary>
        /// This field holds the second dimension upper bound of the integral.
        /// </summary>
        protected double b2;

        /// <summary>
        /// This field holds the bivariate integral.
        /// </summary>
        protected BivariateIntegral integral;

        /// <summary>
        /// Initializes a new instance of the <see cref="AbstractBivariateIntegrator"/> class.
        /// </summary>
        /// <param name="integral">The bivariate integral to integrate.</param>
        protected AbstractBivariateIntegrator(BivariateIntegral integral)
        {
            if (integral == (BivariateIntegral) null)
            {
                throw new ArgumentNullException("integral");
            }

            this.integral = integral;
        }

        /// <summary>
        /// Gets or sets the bivariate integral to integrate.
        /// </summary>
        /// <value>The bivariate integral to integrate.</value>
        public BivariateIntegral Integral
        {
            get { return integral; }
            set { integral = value; }
        }

        /// <summary>
        /// Integrates the integral in a numerical way. After running the numerical integration
        /// it should be checked if the result has a precision error.
        /// </summary>
        /// <param name="parts">The number of parts, in which the function should be divided at the start of the algorithm.</param>
        /// <param name="iterations">The maximum numbers of iterations.</param>
        /// <param name="precision">The minimum precision of the numerical integration.</param>
        /// <returns>The area of the specified integral.</returns>
        public abstract double Integrate(int parts, int iterations, double precision);
    }
}